From: Keir Fraser Date: Sun, 25 Nov 2007 18:06:30 +0000 (+0000) Subject: x86_emulate: Emulate IRET. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14698 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=4abb21480a434074fa0db3d9e5799a7fc3712a1e;p=xen.git x86_emulate: Emulate IRET. Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 9d89e8e652..c6262243ac 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -149,7 +149,7 @@ static uint8_t opcode_table[256] = { ImplicitOps, ImplicitOps, 0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov, /* 0xC8 - 0xCF */ - 0, 0, 0, 0, ImplicitOps, ImplicitOps, ImplicitOps, 0, + 0, 0, 0, 0, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0xD0 - 0xD7 */ ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, @@ -2214,6 +2214,33 @@ x86_emulate( src.val = EXC_OF; goto swint; + case 0xcf: /* iret */ { + unsigned long cs, eip, eflags; + uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM; + if ( !mode_iopl() ) + mask |= EFLG_IOPL; + fail_if(!in_realmode(ctxt, ops)); + fail_if(ops->write_rflags == NULL); + if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), + &eip, op_bytes, ctxt)) || + (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), + &cs, op_bytes, ctxt)) || + (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), + &eflags, op_bytes, ctxt)) ) + goto done; + if ( op_bytes == 2 ) + eflags = (uint16_t)eflags | (_regs.eflags & 0xffff0000u); + eflags &= 0x257fd5; + _regs.eflags &= mask; + _regs.eflags |= (uint32_t)(eflags & ~mask) | 0x02; + if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 ) + goto done; + _regs.eip = eip; + if ( (rc = load_seg(x86_seg_cs, (uint16_t)cs, ctxt, ops)) != 0 ) + goto done; + break; + } + case 0xd4: /* aam */ { unsigned int base = insn_fetch_type(uint8_t); uint8_t al = _regs.eax;